﻿using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal;
using Models.Common;

using System.Data;
using GateWayCloodService.Data;
using UtilsCache;
using GateWayCloodService.Device;
using UtilsBase;
using System.Web;
using UtilsORM;
using UtilsORM.MySql_IotGateway;
namespace GateWayCloodService.CloudCenter
{
    /// <summary>
    /// 场影 条件执行
    /// </summary>
    public class ServiceCloudLinkageConditionV2
    {

        #region
        /// <summary>
        /// 
        /// </summary>
        /// <param name="deviceGuid"></param>
        /// <param name="executeType">0自动运行，1手动运行</param>
        public void linkageConditionAutoRun(string deviceGuid, int executeType)
        {
            try
            {
                EFIotGatewayContext ef = new EFIotGatewayContext();
                List<iot_device_linkage> linkpagelist = UtilRedisNewLife.get<List<iot_device_linkage>>("iot_device_linkage" + deviceGuid + executeType.ToString());
                if (linkpagelist == null)
                {
                    //查出这个设备所有条件
                    linkpagelist = (from lk in ef.iot_device_linkage
                                    join lkc in ef.iot_device_linkage_condition
                                    on lk.l_guid equals lkc.lc_l_guid
                                    where lkc.lc_d_guid == deviceGuid && lkc.lc_operation == "main" && lk.l_status == 0 && lk.l_auto_run == 0 && lkc.lc_status == 0 && lk.l_execute_type == executeType
                                    select lk).Distinct().ToList();
                    UtilRedisNewLife.set<List<iot_device_linkage>>("iot_device_linkage" + deviceGuid + executeType.ToString(), linkpagelist);
                }
                foreach (iot_device_linkage item in linkpagelist)
                {

                    linkage(item);
                }
                ef.Dispose();
            }
            catch (Exception ex)
            {
                Console.WriteLine("  LinkageCondition -----error-------" + ex);
            }
        }

        /// <summary>
        ///处理条件任务
        /// </summary>
        /// <param name="item"></param>
        public void linkage(iot_device_linkage item)
        {
            EFIotGatewayContext ef = new EFIotGatewayContext();
            //判断是否已经正在执行，如果有，就不执行下面了
            iot_device_linkage_condition_handle handleing = ef.iot_device_linkage_condition_handle.Where(c => c.lc_l_guid == item.l_guid).FirstOrDefault();
            if (handleing != null)
            {
                return;
            }


            try
            {
                List<iot_device_linkage_condition> operationMainList = new DBIotDeviceLinkageConditionCache().GetLinkage_Condition(item.l_guid).Where(c => c.lc_operation == "main" && c.lc_status == 0).OrderBy(c => c.lc_order).OrderBy(c => c.lc_id).ToList();
                //条件判断

                int doBoolTrueCount = 0;//条件成立次数
                int doBoolTotalCount = 0;//总条件数
                foreach (iot_device_linkage_condition itemoperation in operationMainList)
                {
                    doBoolTotalCount = doBoolTotalCount + 1;


                    //条件判断是否为真
                    bool itemBool = false;

                    itemBool = getValueMatch(itemoperation);
                    if (itemBool)
                    {
                        doBoolTrueCount = doBoolTrueCount + 1;
                    }

                }

                //判断是否or 或and
                if (item.l_condition_type == "or" && doBoolTrueCount > 0)
                {
                    //只有一个条件成立
                    execute_linkageCondition_forDevice(item);

                    //触发预警
                    // new ServiceIotDeviceWarn().addWarn(item, operationMainList);
                }
                else if (item.l_condition_type == "and" && doBoolTotalCount > 0 && doBoolTotalCount == doBoolTrueCount)
                {
                    //所有条件成立
                    execute_linkageCondition_forDevice(item);

                    //触发预警
                    // new ServiceIotDeviceWarn().addWarn(item, operationMainList);
                }
                else
                {
                    //取消预警
                    //new ServiceIotDeviceWarn().cancelWarn(item, operationMainList);
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                new DBIotSystemLogError().addSystemLogError("linkage 条件处理失败，l_guid:" + item.l_guid, ex.ToString());
            }
        }
        public void execute_linkageCondition_forDevice(iot_device_linkage item)
        {
            string groupGuid = item.l_guid;
            try
            {
                EFIotGatewayContext ef = new EFIotGatewayContext();
                List<iot_device_linkage_condition> operationFollowList = new DBIotDeviceLinkageConditionCache().GetLinkage_Condition(item.l_guid).Where(c => c.lc_operation == "follow" && c.lc_status == 0).OrderBy(c => c.lc_order).ToList();

                //执行内容
                foreach (iot_device_linkage_condition itemfollowoperation in operationFollowList)
                {
                    //Console.WriteLine(itemfollowoperation.lc_d_guid);
                    // Console.WriteLine("+++++++++++++++++++++");
                    if (itemfollowoperation.lc_key == "delay")
                    {
                        //延时
                        addConditionHandle(itemfollowoperation);
                        continue;
                    }
                    //增加处理记录
                    addConditionHandle(itemfollowoperation);
                    updateResult(itemfollowoperation);   /// 更新执行状态
                }


            }
            catch (Exception ex)
            {
                Console.WriteLine("  LinkageCondition -----error-------" + ex);
                new DBIotSystemLogError().addSystemLogError("execute_linkageCondition_forDevice 条件处理失败，l_guid:" + item.l_guid, ex.ToString());
            }

        }
        #endregion

        /// <summary>
        /// 匹配条件是否已经满足
        /// </summary>
        /// <param name="itemoperation"></param>
        /// <returns></returns>
        protected bool getValueMatch(iot_device_linkage_condition itemoperation)
        {

            EFIotGatewayContext ef = new EFIotGatewayContext();
            //查询当前温度是否到设置值
            iot_device_value_current temperaturesensorItem = ef.iot_device_value_current.Where(c => c.vc_d_guid == itemoperation.lc_d_guid && c.vc_key == itemoperation.lc_key).FirstOrDefault();
            if (temperaturesensorItem == null)
            {
                Console.WriteLine(" 条件判断 temperaturesensorItem 空");
                return false;
            }

            iot_device_model_variable variable = new DBIotDeviceVariableCache().getVariableByKey(itemoperation.lc_key);
            if (variable != null)
            {
                if (variable.v_value_type == "number")
                {
                    if (itemoperation.lc_value_rule == ">")
                    {
                        if (double.Parse(temperaturesensorItem.vc_value) > double.Parse(itemoperation.lc_value))
                        {
                            //if (itemoperation.lc_key == "currentFlow")
                            //{//埋点
                            //     new ServiceIotSystemLogError().addSystemLogError(itemoperation.lc_d_guid, "currentFlow：" + temperaturesensorItem.vc_value, "流量计条件触发");
                            // }
                            return true;
                        }
                    }
                    else if (itemoperation.lc_value_rule == "=")
                    {
                        if (double.Parse(temperaturesensorItem.vc_value) == double.Parse(itemoperation.lc_value))
                        {
                            return true;
                        }
                    }
                    else if (itemoperation.lc_value_rule == "<")
                    {
                        if (double.Parse(temperaturesensorItem.vc_value) < double.Parse(itemoperation.lc_value))
                        {
                            return true;
                        }
                    }
                }
                else
                {
                    if (itemoperation.lc_value_rule == "=")
                    {
                        if (temperaturesensorItem.vc_value == (itemoperation.lc_value))
                        {
                            return true;
                        }
                    }
                    else if (itemoperation.lc_value_rule == "!=")
                    {
                        if (temperaturesensorItem.vc_value != (itemoperation.lc_value))
                        {
                            return true;
                        }
                    }
                }
            }

            return false;

        }

        /// <summary>
        /// 更新执行状态
        /// </summary>
        /// <param name="iot_Device_Linkage_Condition"></param>
        private void updateResult(iot_device_linkage_condition iot_Device_Linkage_Condition)
        {
            string sql = "update iot_device_linkage set l_execute_time='" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "' where l_guid='" + iot_Device_Linkage_Condition.lc_l_guid + "' ";
            new MySqlIotGateway().Db.Ado.ExecuteCommand(sql);
        }
        /// <summary>
        /// 插入条件执行记录表
        /// </summary>
        /// <param name="dguid"></param>
        /// <param name="executeTime"></param>
        public void insertExecuteRecord(string dguid)
        {
            linkageConditionAutoRun(dguid, 0);

        }




        public void addConditionHandle(iot_device_linkage_condition model)
        {

            EFIotGatewayContext ef = new EFIotGatewayContext();
            iot_device_linkage_condition_handle handle = new UtilsClassClone().CloneByReflection<iot_device_linkage_condition, iot_device_linkage_condition_handle>(model);
            handle.lc_add_time = DateTime.Now;
            handle.lc_id = 0;
            ef.iot_device_linkage_condition_handle.Add(handle);
            ef.SaveChanges();
            doConditionHandle();

        }
        //private static object obj = new object();
        /// <summary>
        /// 执行条件触发
        /// </summary>
        public void doConditionHandle()
        {
            var lockobj = UtilFreeRedis.getLock("doConditionHandle", 600);
            if (lockobj != null)
            {
                
                //加锁同时只能执行一个,多节点时这里要改成redis锁
                // lock (obj)
                //{
                EFIotGatewayContext ef = new EFIotGatewayContext();
                List<iot_device_linkage_condition_handle> conditions = ef.iot_device_linkage_condition_handle.OrderBy(c => c.lc_id).ToList();
                foreach (iot_device_linkage_condition_handle itemfollowoperation in conditions)
                {

                    try
                    {
                        //判断是否有东西没执完
                        iot_device_linkage_condition_handle hasChild = conditions.Where(c => c.lc_l_guid == itemfollowoperation.lc_l_guid && c.lc_id < itemfollowoperation.lc_id).FirstOrDefault();
                        if (hasChild != null)
                        {
                            continue;
                        }

                        iot_device_model iot_Device_Model = new DBIotDeviceModelCache().getModelByDeviceCache(itemfollowoperation.lc_d_guid);//.getModelListByCache().Where(c => c.m_guid == getDevice.d_model_guid).FirstOrDefault();
                        iot_device_model_type model_Type = new DBIotDeviceModelTypeCache().getModelTypeCache(iot_Device_Model.m_type_guid);///.getModelTypeByDeviceCache(itemfollowoperation.lc_d_guid);
                        if (itemfollowoperation.lc_key == "delay")
                        {
                            //判断是否够时间了
                            DateTime doTime = Convert.ToDateTime(itemfollowoperation.lc_add_time).AddSeconds(double.Parse(itemfollowoperation.lc_value));
                            if (doTime > DateTime.Now)
                            {
                                //还没到执行时间
                                continue;
                            }
                        }
                        else if (model_Type.t_code == "1007" || model_Type.t_code == "1004")//iot_Device_Model.m_code == "1018" || iot_Device_Model.m_code == "1019")
                        {
                            //继电器
                            string value = new UtilRedisHelper().StringGet<string>("deviceValue_" + itemfollowoperation.lc_d_guid);
                            if (!string.IsNullOrEmpty(value) && value == itemfollowoperation.lc_key)
                            {
                                Console.WriteLine("id:" + itemfollowoperation.lc_id + "dguid:" + itemfollowoperation.lc_d_guid + "当前状态 已经是 " + value + ",无需要下发执行 lcguid:" + itemfollowoperation.lc_guid);

                            }
                            else
                            {
                                //查询设备状态状态不是 要执行的状态，就执行
                                new ServiceCloudDeviceCommand().sendCommandToGateWayByGroup(itemfollowoperation.lc_d_guid, itemfollowoperation.lc_key, "条件触发器 lc_guid:" + itemfollowoperation.lc_guid.ToString(), "");
                            }
                        }
                        else if (iot_Device_Model.m_code == "1008")
                        {    //lcd显示屏
                            iot_device_display iot_Device_Display = ef.iot_device_display.Where(c => c.dd_d_guid == itemfollowoperation.lc_d_guid).FirstOrDefault();
                            if (iot_Device_Display == null)
                            {
                                Console.WriteLine(" 执行内容 iot_Device_Jidianqi 数据不存在 " + itemfollowoperation.lc_d_guid);
                                continue;
                            }
                            new ServiceDeviceDisplay().sendCommandToDeviceDisplay1602(new ClientLoginUserInfo(), iot_Device_Display, itemfollowoperation.lc_key);
                        }
                        else
                        {
                            //如果数据欠缺，补全 默认1次，10秒
                            if (itemfollowoperation.lc_repeat_count == null)
                            {
                                itemfollowoperation.lc_repeat_count = 1;
                            }
                            if (itemfollowoperation.lc_repeat_interval == null)
                            {
                                itemfollowoperation.lc_repeat_interval = 10;
                            }
                            new ServiceCloudDeviceCommand().sendCommandToGateWay(itemfollowoperation.lc_d_guid, itemfollowoperation.lc_key, "条件触发器 lc_guid:" + itemfollowoperation.lc_guid.ToString(), "", (int)itemfollowoperation.lc_repeat_count, new UtilsDateTime().getIntervalSeccond((double)(itemfollowoperation.lc_repeat_interval), "ss"));
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.ToString());
                    }

                    ef.iot_device_linkage_condition_handle.Where(c => c.lc_id == itemfollowoperation.lc_id).ExecuteDelete();

                }

                //删除锁
                lockobj.Unlock();
            }
        }
        public void taskRun()
        {
            Task.Run(() =>
            {
                while (true)
                {
                    try
                    {
                        doConditionHandle();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.ToString());
                    }
                    Thread.Sleep(500);
                }
            });
        }
    }
}
